﻿using System;
using System.Collections.Generic;
using System.Drawing;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;

public class CleanWater : MonoBehaviour
{
    public float brushSize = 1;
    public Material targetMaterial = null;
    private Texture2D maskTex = null;
    private RaycastHit result = new RaycastHit();

    private int TextureSize = 512;

    public void CleanSand(Vector3 worldPoint)
    {
        if (targetMaterial == null)
        {
            Debug.Log("材质球没有设置");
            return;
        }

        Vector3 size = gameObject.GetComponent<Renderer>().bounds.size;
        Vector3 position = gameObject.GetComponent<Renderer>().bounds.center;

        if (maskTex == null)
        {
            maskTex = new Texture2D(TextureSize, TextureSize, TextureFormat.RGBA32, false, false);
            UnityEngine.Color[] colorBase = new UnityEngine.Color[TextureSize * TextureSize];

            for (int i = 0; i < colorBase.Length; i++)
            {
                colorBase[i] = new UnityEngine.Color(1, 1, 1, 1);
            }
            maskTex.SetPixels(colorBase);

            Debug.Log("地图宽:" + size.x + " 地图长:" + size.z + " 地图中心点(" + position.x + ":" + position.z + ")");
            targetMaterial.SetVector("_ScaleAndOffset", new Vector4(size.x, size.z, position.x, position.z));
        }

        Ray terrain = new Ray(worldPoint, new Vector3(0, -1, 0));
        bool isValue = Physics.Raycast(terrain, out result, Mathf.Infinity, 1 << gameObject.layer);

        if (!isValue)
        {
            return;
        }

        Vector3 positionWS = result.point;
        positionWS.x = (float)(positionWS.x - position.x + size.x * 0.5);
        positionWS.z = (float)(positionWS.z - position.z + size.z * 0.5);

        Vector2 pixelUV = new Vector2(positionWS.x / size.x, positionWS.z / size.z);

        // 获取笔刷在贴图上的正交大小
        int brushSizeInPourcentX = (int)Mathf.Round(brushSize / size.x * maskTex.width);
        int brushSizeInPourcentY = (int)Mathf.Round(brushSize / size.z * maskTex.height);

        // 计算画笔覆盖的面积
        int PuX = Mathf.FloorToInt(pixelUV.x * maskTex.width);
        int PuY = Mathf.FloorToInt(pixelUV.y * maskTex.height);
        int x = Mathf.Clamp(PuX - brushSizeInPourcentX / 2, 0, maskTex.width - 1);
        int y = Mathf.Clamp(PuY - brushSizeInPourcentY / 2, 0, maskTex.height - 1);
        int width = Mathf.Clamp((PuX + brushSizeInPourcentX / 2), 0, maskTex.width) - x;
        int height = Mathf.Clamp((PuY + brushSizeInPourcentY / 2), 0, maskTex.height) - y;

        // 画笔的透明度
        float[] brushAlpha = new float[brushSizeInPourcentX * brushSizeInPourcentY];

        // 根据画笔形状计算画笔透明度
        int radiusX = Mathf.FloorToInt(brushSizeInPourcentX / 2);
        int radiusY = Mathf.FloorToInt(brushSizeInPourcentY / 2);
        double squareRadius = radiusX * radiusX;

        float xy_rate = size.x / size.z;

        for (int i = 0; i < brushSizeInPourcentX; i++)
        {
            int distanceX = i - radiusX;

            for (int j = 0; j < brushSizeInPourcentY; j++)
            {
                float distanceY = (j - radiusY) / xy_rate;
                double distance = distanceX * distanceX + distanceY * distanceY;

                if (distance > squareRadius)
                {
                    brushAlpha[j * brushSizeInPourcentX + i] = 1;
                }
                else
                {
                    brushAlpha[j * brushSizeInPourcentX + i] = (float)distance / (float)squareRadius;
                }
            }
        }

        // 获取画笔覆盖区域control贴图的颜色
        UnityEngine.Color[] terrainBay = maskTex.GetPixels(x, y, width, height, 0);

        // 计算绘制后的control贴图颜色
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                int index = (i * width) + j;
                float Stronger = brushAlpha[Mathf.Clamp((y + i) - (PuY - brushSizeInPourcentY / 2), 0, brushSizeInPourcentY - 1) * brushSizeInPourcentX + Mathf.Clamp((x + j) - (PuX - brushSizeInPourcentX / 2), 0, brushSizeInPourcentX - 1)];

                UnityEngine.Color color = terrainBay[index];

                if (color.r > Stronger)
                {
                    terrainBay[index] = new UnityEngine.Color(Stronger, Stronger, Stronger, 1);
                }
            }
        }

        // 保存control贴图到内存
        maskTex.SetPixels(x, y, width, height, terrainBay, 0);
        maskTex.Apply();

        targetMaterial.SetTexture("_LerpTex", maskTex);
    }

    // 碰撞查询 (0到1, 1: 从未绘制, 0: 完全绘制)
    public float GetCollision(Vector3 position, int width, int height)
    {
        if (maskTex == null)
        {
            return 1;
        }

        Vector3 size = gameObject.GetComponent<Renderer>().bounds.size;
        Vector3 center = gameObject.GetComponent<Renderer>().bounds.center;

        float X = position.x - center.x + size.x * 0.5f;
        float Y = position.z - center.z + size.z * 0.5f;

        X /= size.x;
        Y /= size.z;

        UnityEngine.Color[] colors = maskTex.GetPixels((int)(maskTex.width * X), (int)(maskTex.height * Y), (int)(width / size.x * maskTex.width), (int)(height / size.z * maskTex.height));

        float number = 0;
        foreach (UnityEngine.Color c in colors )
        {
            number += c.r;
        }

        return number / colors.Length;
    }
}
